2009年03月04日
川俣晶の縁側ソフトウェア技術雑記 total 4791 count

三項演算子に整定数0を含めるとキャスト無しにはushort型の値を得られない問題

Written By: 川俣 晶連絡先

 C#で以下のコードをコンパイルできません。(ソースの抜粋)

ushort a = 1;

ushort c = true ? 0 : a;

 発生するエラーは以下のような内容です。(2行目に対するエラー)

エラー 1 型 'int' を 'ushort' に暗黙的に変換できません。明示的な変換が存在します。(cast が不足していないかどうかを確認してください)

 このエラーが発生するメカニズムは以下の通りです。(引用はC# 3.0言語仕様書より)

  1. 「サフィックスのないリテラルの場合は、int、uint、long、ulong のうち、その値を表すことができる最初の型になります」というルールに従い、0はint型として解釈される
  2. "b ? X : Y"の条件演算子の書式に対して、Xはint型、Yはushort型となる
  3. ここで、「そうではなく、Y から X への暗黙の変換 (6.1 を参照) は存在するが、X から Y へは存在しない場合は、X が条件式の型になります」というルールに従い、条件演算子の結果となる型はXつまりint型となる
  4. 式の型であるint型より、代入すべき変数cの型であるushort型への暗黙変換は存在しないので、コンパイルエラーとなる

 このような型のミスマッチは、通常、定数値に"ul"のようなサフィックスを付け、定数の型を制御することで解消できます。しかし、C#に存在する整数用のサフィックスは"U u L l UL Ul uL ul LU Lu lU lu"しか無く、ushort型の定数を明示的に記述できません。

 そのため、上記のコードをコンパイル可能にするにはキャストを用いて明示的に型を制御するしかないようです。

ushort a = 1;

ushort c = true ? (ushort)0 : a;

感想 §

 最初、なぜエラーになるのか全く理解できず大焦り。ushort型など、普段はまず使うことがないので、このような結果になるとは全く気付いていませんでした。あまりに意外だったので、メモしておきます。